package com.example.itcacp.controller;

import com.example.itcacp.dto.response.Result;
import com.example.itcacp.entity.*;
import com.example.itcacp.repository.mybatis.ProjectMapper;
import com.example.itcacp.service.DataPreparationService;
import com.example.itcacp.repository.mybatis.CollectMapper;
import com.example.itcacp.repository.mybatis.LikeMapper;
import com.example.itcacp.service.*;
import com.example.itcacp.service.impl.BrowseHistoryServiceImpl;
import com.example.itcacp.config.SensitiveWordFilter;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/content")
public class ContentController {
    private static final Logger logger = LoggerFactory.getLogger(WebController.class);
    @Resource
    private ContentService contentService;
    @Resource
    private LikeService likeService;
    @Resource
    private LikeMapper likeMapper;
    @Resource
    private CollectService collectService;
    @Resource
    private CollectMapper collectMapper;
    @Resource
    private BrowseHistoryService browseHistoryService;

    @Resource
    private DataPreparationService dataPreparationService;

    @Resource
    private SensitiveWordFilter sensitiveWordFilter;
    /**
     * 分页查询对应类型的所有内容
     * */
    @GetMapping("/selectContentPage/{contentType}")
    public Result selectContentPage (@RequestParam(defaultValue = "1") Integer pageNum,
                                     @RequestParam(defaultValue = "10") Integer pageSize,
                                     @PathVariable Like.ContentType contentType) {
        PageInfo<Content> bolgPageInfo = contentService.selectContentPage ( pageNum, pageSize, contentType);
        return Result.success ( bolgPageInfo );
    }

    /**
     * 1. 查询对应类型的所有内容
     * 2. 按照浏览篇内容的浏览记录进行排序,返回前十名
     * 3. 结果返回给前端进行展示，每隔三小时刷新一次
     **/
    @GetMapping("/selectHeat")
    public Result selectHeat (@RequestParam Like.ContentType contentType) {
        List<Content> contentList = contentService.selectContentAll ( contentType );
        // 按照 views 字段倒序排序，并取前10条
        List<Content> top10List = contentList.stream()
                .sorted(Comparator.comparingLong((Content c) -> c.getViews() == null ? 0 : c.getViews())
                        .reversed())
                .limit(10)
                .collect( Collectors.toList());
        return Result.success(top10List); // 返回前10条数据
    }

    /**
     * 内容详情查询 ； 每次查询详情时，都更新states
     * */
    @GetMapping("/detail/{contentType}/{contentId}")
    public Result detail (@PathVariable Like.ContentType contentType,
                          @PathVariable Long contentId,
                          @RequestParam(required = false) Long userId) {  // 从请求头中获取浏览内容的用户，如为游客，则不需要userId，直接赋予内容点赞状态为false
        Content contentDetail = contentService.findContentDetailById(contentId, contentType, userId);
        return Result.success (contentDetail);
    }

    /**
     * 查询单个用户的所有同类型文章
     * */
    @GetMapping("/contentByUser/{contentType}")
    public Result contentByUser (@PathVariable Like.ContentType contentType,
                                 @RequestParam Long userId) {   // 此处为内容作者ID
        List<Content> contentList = contentService.selectContentAllByUser (contentType, userId);
        return Result.success (contentList);
    }

    /**
     * 内容创建
     * */
    @PostMapping ("/addContent")
    public Result addContent (@RequestBody Content content) throws IOException {
        try {

            // 敏感词检测
            if (sensitiveWordFilter.containsSensitiveWord (content.getTitle()) ||
                    sensitiveWordFilter.containsSensitiveWord (content.getContent())) {
                return Result.error("内容包含敏感词，请修改后重新发布");
            }

            content.setCreated_at ( new Timestamp ( System.currentTimeMillis () ).toLocalDateTime () );  // 设置创建事件
            contentService.add ( content );  // 保存前端打包的数据到数据库
            // 处理图片路径：从临时目录移动到永久目录
            if (content.getContent () != null) {
                String updatedContent = moveImagesFromTempToContent ( content.getContent () );
                content.setContent ( updatedContent );
                System.out.println (content.getContent ());
            }
            if (content.getCover () != null) {
                String cover = moveImagesFromTempToContent ( content.getCover () );
                content.setCover ( cover );
                System.out.println (content.getCover ());
            }
            // 更新数据库中的封面（包含新的图片路径）
            contentService.updateById ( content );
            if (content.getTags () != null && !content.getTags ().isEmpty ()) {
                content.setTags ( content.getTags () );
                return Result.success ();
            } else {
                return Result.success ();
            }
        }catch (Exception e) {
            logger.error("添加内容失败", e);
            return Result.error("添加内容失败");
        }
    }
    /**
     * 将临时图片移动到永久目录并替换路径
     */
    private String moveImagesFromTempToContent(String content) throws IOException {
        if (content == null) return null;

        // 正则表达式匹配临时图片路径（假设临时路径格式为 /temp/xxx.jpg）
        Pattern pattern = Pattern.compile("/temp/([^\"']+)");
        Matcher matcher = pattern.matcher(content);

        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            String tempFileName = matcher.group(1);
            String tempFilePath = System.getProperty("user.dir") + "/src/main/resources/image/temp/" + tempFileName;
            String permanentFilePath = System.getProperty("user.dir") + "/src/main/resources/image/content/" + tempFileName;
            // 移动文件
            File tempFile = new File(tempFilePath);
            if (tempFile.exists()) {
                File permanentFile = new File(permanentFilePath);
                Files.move(tempFile.toPath(), permanentFile.toPath(), StandardCopyOption.REPLACE_EXISTING);

                // 替换内容中的路径
                String replacement = "/content/" + tempFileName;
                matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
            }
        }
        matcher.appendTail(sb);

        return sb.toString();
    }

    /**
     * 点赞接口
     * */
    @PostMapping("/addLike")
    public Result addLike (@RequestBody Like like) {
        like.setCreated_at ( new Timestamp ( System.currentTimeMillis () ).toLocalDateTime ());
        likeService.addLike ( like );  //添加点赞记录
        Content contentDetail = contentService.findContentDetailById ( like.getTargetId (), like.getTargetType () , like.getUserId () );  // 查询对应内容
        dataPreparationService.handleNewLike ( like.getUserId (), like.getTargetId () );//更新Redis缓存
        return Result.success (contentDetail);  // 返回最新点赞数据
    }

    /**
     * 取消点赞，需要权限
     * */
    @PostMapping("/deleteLike")
    public Result deleteLike (@RequestBody Like like) {
        Like dbLike = likeMapper.findLikeId ( like.getUserId (), like.getTargetId (), like.getTargetType () );
        likeService.removeById ( dbLike );
        Content contentDetail = contentService.findContentDetailById ( like.getTargetId (), like.getTargetType () , like.getUserId () );  // 查询对应内容
        return Result.success (contentDetail);
    }


    /**
     * 收藏接口：需要权限
     * */
    @PostMapping("/addCollect")
    public Result addCollect (@RequestBody Collect collect) {
        collect.setCreated_at ( new Timestamp ( System.currentTimeMillis () ).toLocalDateTime ());
        collectService.addCollect ( collect );  //添加点赞记录
        Content contentDetail = contentService.findContentDetailById ( collect.getTargetId (), collect.getTargetType () , collect.getUserId () );  // 查询对应内容
        return Result.success (contentDetail);  // 返回最新点赞数据
    }

    /**
     * 取消收藏：需要权限
     * */
    @PostMapping("/deleteCollect")
    public Result deleteCollect (@RequestBody Collect collect) {
        Collect dbCollect = collectMapper.findCollectId ( collect.getUserId (), collect.getTargetId (), collect.getTargetType () );
        collectService.removeById ( dbCollect );
        Content contentDetail = contentService.findContentDetailById ( collect.getTargetId (), collect.getTargetType () , collect.getUserId () );  // 查询对应内容
        return Result.success (contentDetail);
    }

    /**
     * 添加历史浏览记录接口
     * */
    @PostMapping("/updateViews")
    public Result updateViews (@RequestBody BrowseHistory browseHistory) {
        browseHistory.setCreated_at ( new Timestamp ( System.currentTimeMillis () ).toLocalDateTime ());
        browseHistoryService.addBrowseHistory ( browseHistory );  //添加点赞记录
        Content contentDetail = contentService.findContentDetailById ( browseHistory.getTargetId (), browseHistory.getTargetType () , browseHistory.getUserId () );  // 查询对应内容
        return Result.success (contentDetail);  // 返回最新浏览数据
    }

    /**
     * 分页查询个人点赞记录
     * */
    @GetMapping("/selectUserLike")
    public Result selectUserLike (@RequestParam(defaultValue = "1") Integer pageNum,
                                  @RequestParam(defaultValue = "10") Integer pageSize,
                                  @RequestParam Long userId) {
        // 1. 查询用户点赞记录
        PageInfo<Like> likePageInfo = likeService.selectUserLikePage ( pageNum, pageSize, userId );
        // 2. 提取contentId列表
        List<Long> contentIds = likePageInfo.getList().stream()
                .map(Like::getTargetId)
                .collect(Collectors.toList());
        // 3. 根据contentId列表查询内容信息
        List<Content> contentList = contentService.selectContentByIds(contentIds);
        // 4. 将内容信息封装到结果中
        Map<String, Object> resultMap = new HashMap<> ();
        resultMap.put("total", likePageInfo.getTotal());
        resultMap.put("pageNum", likePageInfo.getPageNum());
        resultMap.put("pageSize", likePageInfo.getPageSize());
        resultMap.put("contentList", contentList);
        return Result.success (resultMap);
    }

    /**
     * 查询个人点赞记录
     * */
    @GetMapping("/selectUserLikeAll")
    public Result selectUserLike (@RequestParam Long userId) {
        // 1. 查询用户点赞记录
        List<Like> likesByUserId = likeMapper.getLikesByUserId ( userId );
        return Result.success (likesByUserId);
    }

    /**
     * 查询个人浏览记录:除过项目外
     * */
    @GetMapping("/selectUserBrowseHistory")
    public Result selectUserBrowseHistory (@RequestParam(defaultValue = "1") Integer pageNum,
                                           @RequestParam(defaultValue = "10") Integer pageSize,
                                           @RequestParam Long userId,
                                           @RequestParam BrowseHistoryServiceImpl.TimeRange timeRange) {
        PageInfo<BrowseHistory> browseHistoryByTimeRange = browseHistoryService.getBrowseHistoryByTimeRange ( pageNum, pageSize, userId, timeRange );
        // 提取contentId列表
        List<Long> contentIdList = browseHistoryByTimeRange.getList().stream()
                .map(BrowseHistory::getTargetId)
                .collect(Collectors.toList());

        // 根据contentId列表查询内容信息
        List<Content> contentList = contentService.selectContentByIds(contentIdList);
        // 创建contentId到浏览时间的映射
        Map<Long, LocalDateTime> browseTimeMap = browseHistoryByTimeRange.getList().stream()
                .collect(Collectors.toMap(
                        BrowseHistory::getTargetId,
                        BrowseHistory::getCreated_at,
                        (existing, replacement) -> existing  // 如果有重复的contentId，保留第一个（最新的浏览时间）
                ));

        // 构建包含浏览时间的内容列表
        List<Map<String, Object>> resultList = contentList.stream()
                .map(content -> {
                    Map<String, Object> item = new HashMap<>();
                    item.put("content", content);
                    item.put("browseTime", browseTimeMap.get(content.getContentId ()));
                    return item;
                })
                .collect(Collectors.toList());

        // 返回结果
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("total", browseHistoryByTimeRange.getTotal());
        resultMap.put("pageNum", browseHistoryByTimeRange.getPageNum());
        resultMap.put("pageSize", browseHistoryByTimeRange.getPageSize());
        resultMap.put("contentList", resultList);
        return Result.success(resultMap);
    }

    /**
     * 分页查询个人收藏记录
     * */
    @GetMapping("/selectUserCollect")
    public Result selectUserCollect (@RequestParam(defaultValue = "1") Integer pageNum,
                                  @RequestParam(defaultValue = "10") Integer pageSize,
                                  @RequestParam Long userId) {
        // 1. 查询用户点赞记录
        PageInfo<Collect> collectPageInfo = collectService.selectUserCollectPage ( pageNum, pageSize, userId );
        // 2. 提取contentId列表
        List<Long> contentIds = collectPageInfo.getList().stream()
                .map(Collect::getTargetId)
                .collect(Collectors.toList());
        // 3. 根据contentId列表查询内容信息
        List<Content> contentList = contentService.selectContentByIds(contentIds);
        // 4. 将内容信息封装到结果中
        Map<String, Object> resultMap = new HashMap<> ();
        resultMap.put("total", collectPageInfo.getTotal());
        resultMap.put("pageNum", collectPageInfo.getPageNum());
        resultMap.put("pageSize", collectPageInfo.getPageSize());
        resultMap.put("contentList", contentList);
        return Result.success (resultMap);
    }

    /**
     * 分页查询个人所有内容
     * */
    @GetMapping("/selectContentAllByUser")
    public Result selectContentAllByUser (@RequestParam(defaultValue = "1") Integer pageNum,
                                  @RequestParam(defaultValue = "10") Integer pageSize,
                                  @RequestParam Long userId) {
        PageInfo<Content> contentPageInfo = contentService.selectContentAllByUser ( pageNum, pageSize, userId );
        return Result.success (contentPageInfo);
    }

    @GetMapping("selectContentAllByUserId")
    public Result selectContentAllByUserId(@RequestParam Long userId) {
        List<Content> contentList = contentService.selectContentAllByUser ( userId );
        return Result.success (contentList);
    }

    @GetMapping("/searchContent")
    public Result searchContent(@RequestParam String content,
                                @RequestParam Long userId) {
        List<Content> contentList = contentService.searchContent(content, userId);
        return Result.success (contentList);
    }


    @GetMapping("/search")
    public Result search(@RequestParam String query) {
        List<Content> contentList = contentService.search(query);
        return Result.success (contentList);
    }
}
